from turbogears import *
from turbogears import identity, validators

import blockarticle.model as model
import blockarticle.article_view as article_view

def strongly_expire(func):
    """Decorator that sends headers that instruct browsers and proxies not to cache.
    """
    def newfunc(*args, **kwargs):
        import cherrypy
        cherrypy.response.headers['Expires'] = 'Sun, 19 Nov 1978 05:00:00 GMT'
        cherrypy.response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
        cherrypy.response.headers['Pragma'] = 'no-cache'
        return func(*args, **kwargs)
    return newfunc
 
class Article(controllers.Controller):
    @expose(template="blockarticle.templates.article.index")
    def index(self, article_id):
        """Show artile"""
        ArticleID = int(article_id)
        ArticleView = article_view.ArticleView(ArticleID)
        
        Dictionary = {}
        Dictionary['article_header'] = ArticleView.RenderHeader()
        Dictionary['article_content'] = ArticleView.Render()
        Dictionary['article'] = ArticleView.Article
        return Dictionary
    
class ArticleEditor(identity.SecureResource):
    """Controller for manage article"""
    
    # Only admin can access this page
    require = identity.in_group('admin')
    
    @expose(template="blockarticle.templates.article.manage")
    def index(self, article_id):
        ArticleID = int(article_id)
        ArticleView = article_view.ArticleView(ArticleID)
        
        Dictionary = {}
        Dictionary['article_header'] = ArticleView.RenderHeader(DisplayEditable=True)
        Dictionary['article_content'] = ArticleView.Render(DisplayEditable=True)
        Dictionary['article'] = ArticleView.Article
        return Dictionary
    
    @expose()
    @strongly_expire
    def create(self):
        """Create a new article"""
        model.ArticleManager.createArticle('test')
        raise redirect('../article')
    
    @expose('json')
    @strongly_expire
    def insertform(self, **Kwargs):
        """Show insert form
        
        @param article_id: Article's id 
        @param id: Target widget's id
        @param push_back:  Push_back or Insert front 
        """
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        PushBack = Kwargs['push_back']
        
        ArticleView = article_view.ArticleView(ArticleID)
        Content = ArticleView.RenderInsertForm(ID, PushBack = PushBack)
        return dict(command='insertform', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def insert(self, **Kwargs):
        """Insert a node to fromt
        
        @param article_id: Article's id 
        @param type: Type of widget to insert
        @param id: Target widget's id
        @param push_back: Push back or insert front   
        """
        if Kwargs['type'] == '*':
            return dict()
        
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        Type = Kwargs['type']
        PushBack = Kwargs['push_back']
        
        Article = model.Article.get(ArticleID)
        NewWidget = Article.insertWidget(ID, Type, PushBack)

        Content = NewWidget.Render(DisplayEditable = True)
        return dict(command='insert', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def editform(self, **Kwargs):
        """Show edit form of one node
        
        @param article_id: Article's id 
        @param id: Target widget's id 
        """
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        
        ArticleView = article_view.ArticleView(ArticleID)
        Content = ArticleView.RenderEditForm(ID)
        return dict(command='editform', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def modify(self, **Kwargs):
        """Modify the node
        
        @param article_id: Article's id 
        @param id: Target widget's id 
        @param params: Params for modify widget
        """
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        Params = {}
        KwargsWithoutModify = {}
        for Key in Kwargs:
            if Key[:7] == 'modify_':
                Params[Key[7:]] = Kwargs[Key]
            else:
                KwargsWithoutModify[Key] = Kwargs[Key]
        
        Article = model.Article.get(ArticleID)
        ModifiedWidget = Article.modifyWidget(ID, **Params)

        Content = ModifiedWidget.RenderContent(DisplayEditable = True)
        return dict(command='modify', command_args=dict(args=KwargsWithoutModify, content=Content))
    
    @expose('json')
    @strongly_expire
    def cancel(self, **Kwargs):
        """Cancel edit and rerender
        
        @param article_id: Article's id 
        @param id: id to cancel and rerender
        """
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        ArticleView = article_view.ArticleView(ArticleID)
        Content = ArticleView.RerenderNode(ID)
        return dict(command='cancel', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def delete(self, **Kwargs):
        """Delete this node
        
        @param article_id: Article's id 
        @param id: ID of widget to delete 
        """
        ArticleID = int(Kwargs['article_id'])
        ID = int(Kwargs['id'])
        Article = model.Article.get(ArticleID)
        Article.deleteWidget(ID)
        return dict(command='delete', command_args=dict(args=Kwargs))
    
    @expose('json')
    @strongly_expire
    def move(self, **Kwargs):
        """Move this node
        
        @param article_id: Article's id 
        @param id: Source widget's id
        @param to: Target widget's id 
        @param push_back: Push back or insert front   
        """
        ArticleID = int(Kwargs['article_id'])
        From = int(Kwargs['id'])
        To = int(Kwargs['to'])
        PushBack = Kwargs['push_back']
        
        Article = model.Article.get(ArticleID)
        
        if From == To or Article.Doc.IsChildOf(Article.Doc[To], Article.Doc[From]):
            return dict()
        
        MovedWidget = Article.moveWidget(From, To, PushBack)
        
        Content = MovedWidget.Render(DisplayEditable = True)
        return dict(command='move', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def copy(self, **Kwargs):
        """Copy this node
        
        @param article_id: Article's id 
        @param id: Source widget's id
        @param to: Target widget's id 
        @param push_back: Push back or insert front   
        """
        ArticleID = int(Kwargs['article_id'])
        From = int(Kwargs['id'])
        To = int(Kwargs['to'])
        PushBack = Kwargs['push_back']
        
        Article = model.Article.get(ArticleID)
        NewWidget = Article.copyWidget(From, To, PushBack)
        
        Content = NewWidget.Render(DisplayEditable = True)
        return dict(command='copy', command_args=dict(args=Kwargs, content=Content))
    
    @expose('json')
    @strongly_expire
    def modify_title(self, **Kwargs):
        """Modify title
        
        @param article_id: Article's id 
        @param title: Title of article 
        """
        ArticleID = int(Kwargs['article_id'])
        Title = Kwargs['title']
        
        Article = model.Article.get(ArticleID)
        Article.modifyTitle(Title)

        return dict(command='modify_title', command_args=dict(args=Kwargs, title=Title))